#coding=utf-8

module Aio::Parse
  class Parser
    attr_accessor :device_manager
    attr_accessor :parser_machine

    # 重要！在分析前需要确定input_klass
    # input_klass 的类为input模块的类
    # Aio::Module::InputStyle
    attr_accessor :input_klass

    include Aio::Ui::Verbose

    def initialize(device_manager, parser_machine)
      self.device_manager = device_manager
      self.parser_machine = parser_machine

      @invalid_input = Aio::Base::Toolkit::Regexp.merge([
        Aio::Device::Cisco::InvalidInput,
        Aio::Device::H3C::InvalidInput,
        Aio::Device::Huawei::InvalidInput,
        Aio::Device::Maipu::InvalidInput,
        Aio::Device::Juniper::InvalidInput,
      ])
    end

    # 通过巡检文件的方式获得关键信息，并按cmd模块逐个解析
    def parse_by_module

      # 注意这里manager_ip可有可无, 没有的话默认为nil
      print_good "正在加载信息..."
      @input_klass.parse do |device_name, cmd, context, manager_ip|
        device_info = {
          :device_name => device_name,
          :cmd   			 => cmd.strip,
          :context		 => Aio::Text::Context.new(context),
          :manager_ip  => manager_ip
        }

        # 判断 context 是否有效
        next if invalid?(context)

        # 所有判断交到状态机处理
        self.parser_machine.get_device(device_info)
        self.parser_machine.get_full(device_info)
      end
      print_good "信息加载完成"

      # 获取所有设备数量
      total = device_manager.devices_number
      #Aio::Ui::Logger.instance.info = {devices_number: total}

      print_good "总共 #{total} 台设备"
      print_good "正在对各个设备进行分析..."
      device_manager.each_devices_with_index do |name, klass, i|
        # 将解析命令后，并修改了自身类的实例覆盖掉原来父类
        progress_bar(total, i+1, name)

        # Debug处
        if name == "CIB41_CS_H5500SW01"
          #debugger
        end
        new_klass = klass.parse
        device_manager[name] = new_klass.instance
      end
      clear_line
      print_good "设备信息分析完成"
    end

    # 判断 context 是否有效
    def invalid?(context)
      return true if context.empty?
      return true if @invalid_input.match(context[1])
      return false
    end

    # 通过output/compare_xml生成的XML文件解析，直接将结果保存
    # compare_klass 为比较模块
    # 其中只比较useful的值，并不会去比较warning
    # warning 有原本device中以及比较中共同得出
    def parse_by_compare(compare_klass)

      # device_hash 为提供比较文件的hash
      print_good "正在将比较文件转换为内部Hash表"
      device_hash = @input_klass.parse
      compare_klass.device_manager = device_manager
      compare_klass.input_benchmark = device_hash
      compare_hash = compare_klass.parse
      device_manager.merge_warning(compare_hash)
    end

    # 按照两个 device_manager 来进行比较
    def parse_by_compare_with_device_manager(compare_klass, other_device_manager)
      print_good '正在导入device_manager信息'
      compare_klass.device_manager = device_manager
      compare_klass.input_benchmark = other_device_manager
      compare_hash = compare_klass.parse
      device_manager.merge_warning(compare_hash)
    end

  end
end
